﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using Core.DeviceProtocol;
using Core.Model;
using Core.Msg;
using DataServer.Config;

namespace DataServer.View
{
    /// <summary>
    /// DataItemEdit.xaml 的交互逻辑
    /// </summary>
    public partial class DataItemPanel
    {
        private Device _device;
        public Device Device
        {
            get { return _device; }
        }
        private static readonly Dictionary<string,BaseDevProtocol> _devProtocols = new Dictionary<string, BaseDevProtocol>();
        private readonly ObservableCollection<DataItem> _dataItems = new ObservableCollection<DataItem>();

        private bool _isRunning = true;
        
        public DataItemPanel()
        {
            InitializeComponent();
            _gridDataItem.DataContext = this;
            _gridModify.Visibility = _isRunning ? Visibility.Collapsed : Visibility.Visible;
            _propertyGrid.IsEnabled = !_isRunning;
            menuDataitem.IsEnabled = !_isRunning;
        }

        #region 数据选择处理

        public void UpdateDataItems(Device device, List<DataItem> srcItems = null)
        {
            if (_isRunning != AppManager.IsRunning)
            {
                _isRunning = AppManager.IsRunning;
                _gridModify.Visibility = _isRunning?Visibility.Collapsed : Visibility.Visible;
                _propertyGrid.IsEnabled = !_isRunning;
                menuDataitem.IsEnabled = !_isRunning;
            }

            List<DataItem> dataItems;
            if (AppManager.IsRunning)
            {
                 dataItems = AppManager.GetDataItemsByDevice(device);
                _dataItems.Clear();
                if (dataItems?.Count > 0)
                {
                    foreach (DataItem item in dataItems)
                    {
                        _dataItems.Add(item);
                    }
                }

                _gridDataItem.ItemsSource = _dataItems;
                return;
            }
            
            if (_device != null && _dataItems.Count > 0)
            {
                for (int i = 0; i < _dataItems.Count; i++)
                {
                    _dataItems[i].Position = i;
                }
                List<DataItem> items = _dataItems.ToList();
                items = SerializeItems(items);
                Core.Global.DataAccess.SaveDataItems(_device.Id, items);
            }
            _dataItems.Clear();
            _device = device;
            if (_device != null)
            {
                if(srcItems!=null && srcItems.Count > 0)
                {
                    dataItems = srcItems;
                }
                else
                {
                    dataItems = Core.Global.DataAccess.GetDataItems(_device.Id);
                    dataItems = DeSerializeItems(dataItems);
                }
                
                if (dataItems.Count > 0)
                {
                    foreach (DataItem item in dataItems)
                    {
                        _dataItems.Add(item);
                    }
                }
            }
            _gridDataItem.ItemsSource = _dataItems;
        }
       
        private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_gridDataItem.SelectedItems.Count > 1)
            {
                //foreach (object item in _gridDataItem.SelectedItems)
                //{
                //    var dataItem = item as DataItem;
                //    if (dataItem != null && !string.IsNullOrEmpty(dataItem.SubInfo) && dataItem.TagObject == null)
                //    {
                //        dataItem = DeSerializeItem(dataItem);
                //    }
                //}
                _propertyGrid.SelectedObject = _gridDataItem.SelectedItems;
            }
            else
            {
                //var dataItem = _gridDataItem.SelectedItem as DataItem;
                //if (dataItem != null && !string.IsNullOrEmpty(dataItem.SubInfo) && dataItem.TagObject == null)
                //{
                //    dataItem = DeSerializeItem(dataItem);
                //}
                _propertyGrid.SelectedObject = _gridDataItem.SelectedItem;
            }
            _propertyGrid.ExpandAllProperties();
        }

        #endregion

        #region 加载保存数据

        private void BtnLoadDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            if (_device != null)
            {
                _dataItems.Clear();
                List<DataItem> dataItems = Core.Global.DataAccess.GetDataItems(_device.Id);
                dataItems = DeSerializeItems(dataItems);
                if (dataItems?.Count > 0)
                {
                    foreach (DataItem item in dataItems)
                    {
                        _dataItems.Add(item);
                    }
                }
                _gridDataItem.ItemsSource = _dataItems;
            }
        }

        private void BtnSaveDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            if (_device != null)
            {
                for (int i = 0; i < _dataItems.Count; i++)
                {
                    _dataItems[i].Position = i;
                }
                List<DataItem> items = _dataItems.ToList();
                items = SerializeItems(items);
                if (Core.Global.DataAccess.SaveDataItems(_device.Id, items))
                {
                    MessageBox.Show("保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }
            }
            MessageBox.Show("保存失败!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
        }


        #endregion

        #region 添加删除移动数据项

        private void MiAddDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            if (_device == null)
            {
                MessageBox.Show("添加失败,请先选择设备!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (string.IsNullOrEmpty(_device.Protocol))
            {
                MessageBox.Show("添加失败,请先选择设备通信协议!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            DataItem insert;
            var sel = _gridDataItem.SelectedItem as DataItem;
            if (sel != null)
            {
                int index = _dataItems.IndexOf(sel);
                insert = new DataItem(sel);
                insert = DecorateItem(insert);
                _dataItems.Insert(index + 1, insert);
            }
            else
            {
                insert = new DataItem("新数据项", _device.Id);
                insert = DecorateItem(insert);
                _dataItems.Add(insert);
            }
            _gridDataItem.SelectedItem = insert;
        }
        private void MiDelDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            int count = _gridDataItem.SelectedItems.Count, index = 0;
            while (_gridDataItem.SelectedItems.Count > 0)
            {
                var del = _gridDataItem.SelectedItems[0] as DataItem;
                if (del != null) _dataItems.Remove(del);
                index++;
                if (index >= count)
                    break;
            }
        }
        private void BtnAddDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            if (_device == null)
            {
                MessageBox.Show("添加失败,请先选择设备!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (string.IsNullOrEmpty(_device.Protocol))
            {
                MessageBox.Show("添加失败,请先选择设备通信协议!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            var sel = _dataItems.Count > 0 ? _dataItems[_dataItems.Count - 1] : null;
            for (int i = 0; i < _intUpDown.Value; i++)
            {
                if (sel != null)
                {
                    int index = _dataItems.IndexOf(sel);
                    sel = new DataItem(sel);
                    sel = DecorateItem(sel);
                    _dataItems.Insert(index + 1, sel);
                }
                else
                {
                    sel = new DataItem("新数据项", _device.Id);
                    sel = DecorateItem(sel);
                    _dataItems.Add(sel);
                }
            }

            _gridDataItem.SelectedItem = _dataItems[_dataItems.Count - 1];
        }
        private void BtnDelDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            int count = _gridDataItem.SelectedItems.Count, index = 0;
            while (_gridDataItem.SelectedItems.Count > 0)
            {
                var del = _gridDataItem.SelectedItems[0] as DataItem;
                if (del != null) _dataItems.Remove(del);
                index++;
                if (index >= count)
                    break;
            }
        }
        private void MiUp_OnClick(object sender, RoutedEventArgs e)
        {
            var sel = _gridDataItem.SelectedItem as DataItem;
            if (sel != null)
            {
                int index = _dataItems.IndexOf(sel);
                if (index > 0)
                    _dataItems.Move(index, index - 1);
            }
            else
            {
                MessageBox.Show("请先选择数据项!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
        private void MiDown_OnClick(object sender, RoutedEventArgs e)
        {
            var sel = _gridDataItem.SelectedItem as DataItem;
            if (sel != null)
            {
                int index = _dataItems.IndexOf(sel);
                if (index < _dataItems.Count - 1)
                    _dataItems.Move(index, index + 1);
            }
            else
            {
                MessageBox.Show("请先选择数据项!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
        
        #endregion

        #region 导入导出数据项

        private void BtnImportDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            var dataitems = ConfigManager.ImportDeviceConfig(_device);
            if (dataitems != null)
            {
                dataitems = DeSerializeItems(dataitems);
                if (dataitems.Count > 0)
                {
                    _dataItems.Clear();
                    foreach (DataItem item in dataitems)
                    {
                        _dataItems.Add(item);
                    }
                }
                MessageBox.Show("导入成功!", "提示",MessageBoxButton.OK,MessageBoxImage.Information);
            }
        }
        private void BtnExportDataItem_OnClick(object sender, RoutedEventArgs e)
        {
            ConfigManager.ExportDeviceConfig(_device, _dataItems.ToList());
        }


        #endregion

        #region 数据项额外参数处理
        /// <summary>
        /// 将数据项额外参数序列化
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        private List<DataItem> SerializeItems(List<DataItem> items)
        {
            if (_devProtocols.ContainsKey(_device.Protocol)) 
            {
                items = _devProtocols[_device.Protocol].SerializeDataItems(items);
            }
            return items;
        }
        /// <summary>
        /// 将额外参数反序列化
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        private List<DataItem> DeSerializeItems(List<DataItem> items)
        {
            if (!_devProtocols.ContainsKey(_device.Protocol))   // 处理跟协议相关的数据项信息
            {
                BaseDevProtocol protocol = _device.GetBaseDevProtocol();
                if (protocol != null)
                {
                    _devProtocols.Add(_device.Protocol, protocol);
                    items = protocol.DeSerializeDataItems(items);
                }
            }
            else
            {
                items = _devProtocols[_device.Protocol].DeSerializeDataItems(items);
            }
            return items;
        }
        private DataItem DeSerializeItem(DataItem item)
        {
            if (!_devProtocols.ContainsKey(_device.Protocol))   // 处理跟协议相关的数据项信息
            {
                BaseDevProtocol protocol = _device.GetBaseDevProtocol();
                if (protocol != null)
                {
                    _devProtocols.Add(_device.Protocol, protocol);
                    item = protocol.DeSerializeDataItem(item);
                }
            }
            else
            {
                item = _devProtocols[_device.Protocol].DeSerializeDataItem(item);
            }
            return item;
        }
        /// <summary>
        /// 给数据项添加额外参数
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private DataItem DecorateItem(DataItem item)
        {
            if (_devProtocols.ContainsKey(_device.Protocol)) 
            {
                item = _devProtocols[_device.Protocol].DecorateItem(item);
            }
            return item;
        }
        #endregion

      
    }

    public class HexConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is Int32)) return "0000";
            int val = (int)value;
            return val.ToString("X04");
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString())) return 0;
           return System.Convert.ToInt32(value.ToString(), 16);
        }
    }
}
